package org.dk.poitalk.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspFactory;
import javax.servlet.jsp.PageContext;

import org.dk.poitalk.exception.DuplicateEntityException;
import org.dk.poitalk.model.EntityClient;
import org.dk.poitalk.model.TipoEntityClient;
import org.dk.poitalk.service.entity.EntityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.core.io.support.PropertiesLoaderSupport;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.support.HttpRequestHandlerServlet;
import org.springframework.web.servlet.LocaleResolver;

import com.google.apphosting.api.DatastorePb.GetRequest;
import com.jappstart.model.auth.UserAccount;
import com.jappstart.service.auth.EnhancedUserDetailsService;
import com.jappstart.service.cache.CacheService;

@Controller
@RequestMapping("/claim")
@SessionAttributes(ClaimController.CLAIM)
public class ClaimController {
	private static final Logger logger = Logger.getLogger(ClaimController.class
			.getName());


	protected static final String CLAIM = "claim";
	
	private EntityService entityService;

	private LocaleResolver localeResolver;
	
	private EnhancedUserDetailsService userDetailsService;

	private MessageSource messageSource;
	
	public EntityService getEntityService() {
		return entityService;
	}

	@Autowired
	public void setEntityService(EntityService entityService) {
		this.entityService = entityService;
	}

	/**
	 * Gets the locale resolver.
	 * 
	 * @return the locale resolver
	 */
	public final LocaleResolver getLocaleResolver() {
		return localeResolver;
	}

	/**
	 * Sets the locale resolver.
	 * 
	 * @param localeResolver
	 *            the locale resolver
	 */
	@Autowired
	public final void setLocaleResolver(final LocaleResolver localeResolver) {
		this.localeResolver = localeResolver;
	}
	
	/**
	 * Gets the user details service.
	 * 
	 * @return the user details service
	 */
	public final EnhancedUserDetailsService getUserDetailsService() {
		return userDetailsService;
	}

	/**
	 * Sets the user details service.
	 * 
	 * @param userDetailsService
	 *            the user details service
	 */
	@Autowired
	public final void setUserDetailsService(
			final EnhancedUserDetailsService userDetailsService) {
		this.userDetailsService = userDetailsService;
	}

	

	public MessageSource getMessageSource() {
		return messageSource;
	}
	
	@Autowired
	public void setMessageSource(MessageSource messageSource) {
		this.messageSource = messageSource;
	}

	@RequestMapping(value = "/claim", method = RequestMethod.GET)
    public final String create() {
        return "claim";
    }	

    /**
     * Determines if an account with the given username exists or not.
     *
     * @param request the request
     * @return the response
     */
    @RequestMapping(value = "/addx", method = RequestMethod.POST)
    @ResponseBody
    public final Map<String, Boolean> addx(
        @RequestBody final Map<String, String> request) {
        final Map<String, Boolean> response = new HashMap<String, Boolean>();
		String username = ((UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();        	
        EntityClient entityClientIN = new EntityClient(request.get("idplace").toString(),TipoEntityClient.GOOGLEPLACE,null);
		Boolean isAdded = false;
		HashMap<String,String> paramValue= new HashMap<String, String>();
		paramValue.put(EntityService.IDPLACE,entityClientIN.getIdPlace());
		EntityClient rEntityClientIN = this.getEntityService().findById(paramValue);
		if (rEntityClientIN == null){
			
			isAdded = getUserDetailsService().addEntityClient(entityClientIN, username);
	        logger.info(String.format("Entity to addx:saveOrUpdate: %s with Key", entityClientIN.toString(),entityClientIN.getKey()));
        
	        if (!isAdded) {
	        	logger.info("addx response put to added = false");
	            response.put("added", false);
	        } else {
	        	logger.info("addx response put to added = true");
	            response.put("added", true);
	        }
	        
		}
        return response;
    } 

    /**
     * Determines if an account with the given username exists or not.
     *
     * @param request the request
     * @return the response
     */
    @RequestMapping(value = "/deletex", method = RequestMethod.POST)
    @ResponseBody
    public final Map<String, Boolean> deletex(
        @RequestBody final Map<String, String> request) {
        final Map<String, Boolean> response = new HashMap<String, Boolean>();
		String username = ((UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();        	
		final UserAccount rUserAccount = this.getUserDetailsService().getUser(username);
        EntityClient entityClientIN = new EntityClient(request.get("idplace").toString(),TipoEntityClient.GOOGLEPLACE,rUserAccount);
		logger.info(String.format("Entity to deletex:findBy: %s", entityClientIN));
        int resultUpdate = this.getEntityService().delete(entityClientIN);
        ((CacheService<UserAccount>)this.getUserDetailsService()).removeEntityCache(rUserAccount);
        if ((resultUpdate == 1)){
        	response.put("deleted", true);
        } else {
        	response.put("deleted", false); 
		}

        return response;
    }
    
    private  List<Map<String,Object>> generateDataTable (List<EntityClient> entityClients,HttpServletRequest request){

    	List<Map<String,Object>> listDataTable = new ArrayList<Map<String,Object>>();
    	Map<String,Object> mapDataRows= null;
		
		UserAccount userAccount1 = null;
		
		for (EntityClient entityClient : entityClients) {
			mapDataRows = new HashMap<String, Object>();
			String addressServletFeedbacking = this.messageSource.getMessage("address.servlet.feedbacking", null, getLocaleResolver().resolveLocale(request));
			mapDataRows.put("keyQRCode",addressServletFeedbacking + "?idplace=" + entityClient.getIdPlace() + "&tipoentityclient=" + TipoEntityClient.GOOGLEPLACE);
			mapDataRows.put("idPlace",entityClient.getIdPlace());
			mapDataRows.put("tipoEntityClient",entityClient.getTipoEntityClient());
			userAccount1 = entityClient.getUserAccount();
			mapDataRows.put("username",userAccount1.getUsername());
			logger.info(String.format("resultAdhoc tiene la siguiente pinta %s",mapDataRows));
			listDataTable.add(mapDataRows);
		}
		
		return listDataTable;
    }
    /**
     * TODO SearchX ahora devuelve la lista de paginación, desde memoria, cambiar
     * TODO SearchX ahora si no hay contenido devuelve una badREquest
     * 
     * @param dataTablesRequest
     * @param response
     * @return
     */
    /** TODO Cambiar Cuando quede uno que lo refresque*/
    @RequestMapping(value="/searchx", method= RequestMethod.POST)
    public @ResponseBody
    DataTablesResponse<Map<String,Object>> searchx(@RequestBody DataTablesRequest dataTablesRequest, HttpServletRequest request, HttpServletResponse response) {
       
		logger.info(String.format("La dataTablesRequest contiene  %s = ",
				dataTablesRequest.toString()));
		

    	DataTablesResponse<Map<String,Object>> dataTablesResponse = new DataTablesResponse<Map<String,Object>>();

//      List<EntityClient> listDataTable = entityService.search(null);
    	
		String username = ((UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();        	
		UserAccount userAccount = getUserDetailsService().getUser(username);
		List<EntityClient> entityClients = userAccount.getEntityClients();
		logger.info(String.format("La searchx devuelve  %d filas",entityClients.size()));	
		
		List<Map<String,Object>> listDataTable = this.generateDataTable(entityClients,request);
		
		
        if (!listDataTable.isEmpty()) {
        	dataTablesResponse.echo = dataTablesRequest.echo;
        	dataTablesResponse.totalRecords = listDataTable.size();
        	dataTablesResponse.totalDisplayRecords = listDataTable.size();
        	int endSubList = ((dataTablesRequest.displayStart+dataTablesRequest.displayLength)>listDataTable.size())?listDataTable.size():(dataTablesRequest.displayStart+dataTablesRequest.displayLength);
        	dataTablesResponse.data = listDataTable.subList(dataTablesRequest.displayStart,endSubList);
        	dataTablesResponse.columns = "{idPlace,tipoEntityClient,username,null}";
        }
//        else {
//            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);        	      	
//         }
        return dataTablesResponse;
    }
      
}
